/**
 * @param {number[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
// 豆包的回答答案
var gameOfLife = function (board) {
  const m = board.length;
  const n = board[0].length;

  // 定义八个方向的偏移量，用于检查周围的细胞
  const directions = [
    [-1, -1], [-1, 0], [-1, 1],
    [0, -1], [0, 1],
    [1, -1], [1, 0], [1, 1]
  ];

  // 辅助函数：计算指定位置周围的活细胞数量
  function countLiveNeighbors(i, j) {
    let count = 0;
    for (const [dx, dy] of directions) {
      const x = i + dx;
      const y = j + dy;
      // 检查坐标是否合法，并且当前细胞是否为活细胞（1）或曾经是活细胞（2）
      if (x >= 0 && x < m && y >= 0 && y < n) {
        if (board[x][y] === 1 || board[x][y] === 2) {
          count++;
        }
      }
    }
    return count;
  }

  // 第一次遍历：标记每个细胞的下一个状态
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      const liveNeighbors = countLiveNeighbors(i, j);

      if (board[i][j] === 1) {
        // 当前是活细胞
        if (liveNeighbors < 2 || liveNeighbors > 3) {
          // 情况1或3：活细胞死亡，标记为2（1→0）
          board[i][j] = 2;
        }
      } else {
        // 当前是死细胞
        if (liveNeighbors === 3) {
          // 情况4：死细胞复活，标记为3（0→1）
          board[i][j] = 3;
        }
      }
    }
  }

  // 第二次遍历：将标记转换为最终状态
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (board[i][j] === 2) {
        board[i][j] = 0; // 曾经的活细胞现在死亡
      } else if (board[i][j] === 3) {
        board[i][j] = 1; // 曾经的死细胞现在复活
      }
    }
  }
};

/**
 * @param {number[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
// leetcode 上面优秀的答案
var gameOfLife = function (board) {
  const copyBoard = board.map(i => ([...i]));
  const dirs = [[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1]];
  for (let i = 0; i < copyBoard.length; i++) {
    for (let j = 0; j < copyBoard[0].length; j++) {
      let liveCount = 0;
      for (let dir of dirs) {
        if (copyBoard?.[i + dir[0]]?.[j + dir[1]]) {
          liveCount++;
        }
      }
      if (board[i][j] && (liveCount < 2 || liveCount > 3)) {
        board[i][j] = 0;
      }
      if (board[i][j] === 0 && liveCount === 3) {
        board[i][j] = 1;
      }
    }
  }
};